#include <iostream>
extern "C"
{
    #include <libavformat/avformat.h>
}
#include "MYDemux.h"
#include "MYVideoThread.h"
#include "MYAudioThread.h"
#include "MYDecode.h"
#include "MYDemuxThread.h"

#include <QDebug>




using namespace std;

MYDemuxThread::MYDemuxThread()
{

}

// 创建对象并打开
bool MYDemuxThread::Open(const char *url, IVideoCall *call)
{
    if(url == nullptr || url[0] == '\0') return false;

    mux.lock();
    // 初始化解封装器，视频解码器，音频解码器
    if (!demux) demux = new MYDemux();
    if (!vt) vt = new MYVideoThread();
    if (!at) at = new MYAudioThread();

    // 打开解封装
    bool ret = demux->Open(url);
    if(!ret) {
        mux.unlock();
        cout << "demux->Open(url) failed!" << endl;
        return false;
    }

    setOpenSuccess(true); // 打开成功

    // 打开视频解码器和处理线程
    if(!vt->Open(demux->CopyVPara(), call, demux->width, demux->height)) {
        ret = false;
        cout << "vt->Open failed!" << endl;
    }
    // 打开音频解码器和处理线程
    if(!at->Open(demux->CopyAPara(), demux->sampleRate, demux->channels)) {
        ret = false;
        cout << "at->Open failed!" << endl;
    }
    totalMs = demux->totalMs;
    mux.unlock();
    cout << "MYDemuxThread::Open " << ret << endl;
    return ret;
}

void MYDemuxThread::Clear()
{
    mux.lock();
    if(demux) demux->Clear();
    if(vt) vt->Clear();
    if(at) at->Clear();
    mux.unlock();
}

void MYDemuxThread::Close()
{
    isExit = true;
    // 等待线程结束
    wait();
	if (demux) demux->Close();
	if (vt) vt->Close();
	if (at) at->Close();
    mux.lock();
    // 停止线程
    QThread::quit();
    delete demux;
	delete at;
    delete vt;
    demux = nullptr;
    vt = nullptr;
    at = nullptr;
    openSuccess = false;
    mux.unlock();
}

void MYDemuxThread::SetPause(bool isPause)
{
    mux.lock();
    this->isPause = isPause;
    if(at) at->SetPause(isPause);
    if(vt) vt->SetPause(isPause);
    mux.unlock();
}

void MYDemuxThread::SetVolume(double newVolume)
{
    if(!at) return;
    at->SetVolume(newVolume);
}

void MYDemuxThread::setOpenSuccess(bool value)
{
    openSuccess = value;
}

bool MYDemuxThread::getOpenSuccess()
{
    return openSuccess;
}

void MYDemuxThread::Start()
{
    mux.lock();
    if (!demux) demux = new MYDemux();
    if (!vt) vt = new MYVideoThread();
    if (!at) at = new MYAudioThread();
    // 启动当前线程
    QThread::start();
    if(vt) vt->start();
    if(at) at->start();
    mux.unlock();
}

void MYDemuxThread::run()
{
    while(!isExit) {
        mux.lock();
        if(isPause || !demux) {
            mux.unlock();
            msleep(5);
            continue;
        }

        // 音视频同步
        if(vt && at) {
            pts = at->pts;
            vt->synpts = at->pts;
        }

        AVPacket *pkt = demux->Read();
        if(!pkt) {
            mux.unlock();
            msleep(5);
            continue;
        }

        // 判断数据是否是音频, 发送到各自的解码器解码
        if(demux->IsAudio(pkt)) {
            if(at) at->Push(pkt);
        }
        else {
            if(vt) vt->Push(pkt);
        }
        mux.unlock();
        msleep(1);
    }
}

// pos是个百分比值 0.0-1.0
void MYDemuxThread::Seek(double pos)
{
    // 1.清空demux，音频解码线程、视频解码线程 缓存
    Clear();
    mux.lock();
    bool status = this->isPause;
    mux.unlock();
    // 2.暂停 demux 线程、音频解码线程、视频解码线程
    SetPause(true);

    mux.lock();
    if(demux) demux->Seek(pos);
    mux.unlock();

    // 实际要显示位置的pts
    long long seekPts = pos * demux->totalMs;
	qDebug() << "seekpts:" << seekPts;

    while(!isExit) {
        AVPacket *pkt = demux->ReadVideo();
        if(!pkt) break;
        // 如果解码到seekpts 就退出 可以正常播放了
        if(vt->RepaintPts(pkt, seekPts)) {
            this->pts = seekPts;
            break;
        }
        // av_packet_free(&pkt);
        // 否则就继续读出帧，处理掉没用的数据帧
    }
    if(!status) SetPause(false);

}

MYDemuxThread::~MYDemuxThread()
{
    isExit = true;
    wait();
}
